package datasource_bak

import (
	"database/sql"
	"gitee.com/kristas/booting-go/framework/core/bean"
	"gitee.com/kristas/booting-go/framework/core/statement/types"
	"reflect"
)

type Datasource interface {
	bean.Bean
	Tag() string
	GetType() string
	GetHost() string
	GetDatabase() string
	GetUsername() string
	GetPassword() string
	GetTunnel() string

	GetConnMaxLifeTime() int64
	GetConnMaxIdleTime() int64
	GetMaxIdleConns() int
	GetMaxOpenConns() int
	IsLazyFetch() bool
}

type Config struct {
	types.Component
	prefix string

	Type            string `yaml:"type"`
	Host            string `yaml:"host"`
	Database        string `yaml:"database"`
	Username        string `yaml:"username"`
	Password        string `yaml:"password"`
	Tunnel          string `yaml:"tunnel"`
	ConnMaxLifeTime int64  `yaml:"max_life_time"`
	ConnMaxIdleTime int64  `yaml:"max_idle_time"`
	MaxIdleConns    int    `yaml:"max_idle_conn"`
	MaxOpenConns    int    `yaml:"max_open_conn"`
	LazyFetch       bool   `yaml:"lazy_fetch"`
}

func (c *Config) Prefix() string {
	if c.prefix == "" {
		return "application.datasource"
	}
	return c.prefix
}

type DataBaseConnectionHandler func(d *Starter, configure Datasource) (*sql.DB, error)

type ORMUpgrader interface {
	bean.Bean
	UpgradeType() reflect.Type
	Upgrade(wrapper Wrapper) (interface{}, error)
}

type Wrapper interface {
	DB() *sql.DB
	Configure() Datasource
}

func newDatasourceWrapper(DB *sql.DB, configure Datasource) Wrapper {
	return &defaultWrapper{
		db:        DB,
		configure: configure,
	}
}

type defaultWrapper struct {
	db        *sql.DB
	configure Datasource
}

func (d *defaultWrapper) DB() *sql.DB {
	return d.db
}

func (d *defaultWrapper) Configure() Datasource {
	return d.configure
}
